﻿using System;
using System.Collections.Generic;
using WindowsPhoneMvp.Navigation;
using Autofac;

namespace WindowsPhoneMvp.Binder.PresenterFactory
{
    public class AutofacPresenterFactory : IPresenterFactory
    {
        readonly IContainer container;

        readonly IDictionary<IPresenter, ILifetimeScope> presentersToContainers = new Dictionary<IPresenter, ILifetimeScope>();
        readonly object presentersToContainersSyncLock = new object();

        public AutofacPresenterFactory(IContainer container)
        {
            this.container = container;
        }

        public IPresenter Create(Type presenterType, Type viewType, IView viewInstance)
        {
            var requestScope = container.BeginLifetimeScope(builder =>
                    {
                        builder.RegisterType(presenterType).InstancePerLifetimeScope();
                        builder.RegisterInstance(viewInstance)
                            .AsSelf()
                            .As(viewType.GetInterfaces());
                    }
                );

            var presenter = (IPresenter)requestScope.Resolve(presenterType);
            //support property binding of navigation service
            if(presenter.Navigate == null) presenter.Navigate = requestScope.Resolve<INavigationService>();

            lock (presentersToContainersSyncLock)
            {
                presentersToContainers[presenter] = requestScope;
            }

            return presenter;
        }

        public void Release(IPresenter presenter)
        {
            var presenterScopedContainer = presentersToContainers[presenter];
            lock (presentersToContainersSyncLock)
            {
                presentersToContainers.Remove(presenter);
            }

            // Disposing the container will dispose any of the components
            // created within it's lifetime scope.
            presenterScopedContainer.Dispose();
        }
    }
}